package krasa.toolwindow; import static krasa.actions.AutotestUtils.getTestFileRelativePath; import java.awt.*; import java.awt.datatransfer.StringSelection; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Collection; import java.util.HashSet; import java.util.Set; import javax.swing.*; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import com.intellij.icons.AllIcons; import com.intellij.ide.CopyProvider; import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; import com.intellij.notification.Notifications; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileEditor.OpenFileDescriptor; import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.pom.Navigatable; import com.intellij.psi.PsiFile; import com.intellij.psi.search.PsiShortNamesCache; import com.intellij.ui.PopupHandler; import com.intellij.ui.components.JBList; import krasa.actions.DebugAutotestInIntelliJ; import krasa.actions.DialogUtils; import krasa.actions.RunAutotestInIntelliJ; import krasa.model.AutotestState; import krasa.model.TestFile; public class AutotestPanel implements Disposable { private final Runnable settingsChangedListener; private JBList list; private JPanel root; private DefaultListModel model; private Project project; public AutotestPanel(Project project) { this.project = project; initializeModel(); settingsChangedListener = new Runnable() { @Override public void run() { initializeModel(); } }; AutotestState.getInstance().addListener(settingsChangedListener); } private final CopyProvider myCopyProvider = new CopyProvider() { @Override public void performCopy(@NotNull DataContext dataContext) { final TestFile value = (TestFile) list.getSelectedValue(); CopyPasteManager.getInstance().setContents( new StringSelection(String.valueOf(value.getName() + " " + value.getEnviroment()))); } @Override public boolean isCopyEnabled(@NotNull DataContext dataContext) { return list.getSelectedValue() != null; } @Override public boolean isCopyVisible(@NotNull DataContext dataContext) { return false; } }; public CopyProvider getCopyProvider() { return myCopyProvider; } public JPanel getRoot() { return root; } private void createUIComponents() { model = new DefaultListModel(); list = createJBList(model); list.addMouseListener(new PopupHandler() { @Override public void invokePopup(Component comp, int x, int y) { int index = list.locationToIndex(new Point(x, y)); if (index >= 0) { if (!list.isSelectedIndex(index)) { list.setSelectedIndex(index); } ActionManager.getInstance().createActionPopupMenu("", new ActionGroup() { @NotNull @Override public AnAction[] getChildren(@Nullable AnActionEvent e) { return new AnAction[] { new RunAction(), new RunOnAction(), new DebugAction(), new Separator(), new DeleteAction(), new JumpToSourceAction() }; } }).getComponent().show(comp, x, y); } } }); } private JBList createJBList(DefaultListModel pluginsModel) { JBList jbList = new JBList(pluginsModel); jbList.setCellRenderer(new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { final Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); TestFile goal = (TestFile) value; String env = goal.getEnviroment(); env = env.replace("prgen", "p"); env = env.replace("tmdev-localhost", "localhost"); setText("[" + env + "] " + goal.getName()); return comp; } }); jbList.addMouseListener(new DoubleClickListener()); jbList.addKeyListener(new EnterListener()); jbList.addKeyListener(new DeleteListener()); jbList.addKeyListener(new JumpToSourceListener()); jbList.setDataProvider(new DataProvider() { @Nullable @Override public Object getData(@NonNls String dataId) { if (CommonDataKeys.NAVIGATABLE_ARRAY.is(dataId)) { jumpToSource(); return new Navigatable[] { new Navigatable() { @Override public void navigate(boolean b) { jumpToSource(); } @Override public boolean canNavigate() { return true; } @Override public boolean canNavigateToSource() { return true; } } }; } else return null; } }); return jbList; } private void initializeModel() { model.clear(); Collection<TestFile> testFileHistory = AutotestState.getInstance().getTestFileHistory(); for (TestFile testFile : testFileHistory) { model.addElement(testFile); } } @Override public void dispose() { AutotestState.getInstance().removeListener(settingsChangedListener); } private void jumpToSource() { TestFile selectedValue = (TestFile) list.getSelectedValue(); if (selectedValue != null) { String path = selectedValue.getPath(); PsiFile[] filesByName = PsiShortNamesCache.getInstance(project).getFilesByName(selectedValue.getName()); for (PsiFile psiFile : filesByName) { if (getTestFileRelativePath(psiFile.getVirtualFile()).equals(path)) { OpenFileDescriptor n = new OpenFileDescriptor(project, psiFile.getVirtualFile(), 0).setUseCurrentWindow(true); if (n.canNavigate()) { n.navigate(true); return; } } } final Notification notification = new Notification("Autotest ERROR", "", "File not found " + selectedValue.getPath(), NotificationType.ERROR); ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { Notifications.Bus.notify(notification, project); } }); } } private void delete() { for (Object o : list.getSelectedValues()) { TestFile o1 = (TestFile) o; AutotestState.getInstance().removeTestFileHistory(o1); } } private void run() { for (Object o : list.getSelectedValues()) { TestFile o1 = (TestFile) o; new RunAutotestInIntelliJ().runInIDEA(project, o1); } } private void debug() { for (Object o : list.getSelectedValues()) { TestFile o1 = (TestFile) o; new DebugAutotestInIntelliJ().debugInIDEA(project, o1); } } private TestFile getTestFileAtPoint(Point point) { int index = list.locationToIndex(point); return (TestFile) model.get(index); } private class JumpToSourceListener extends KeyAdapter { @Override public void keyPressed(KeyEvent e) { final int keyCode = e.getKeyCode(); if (keyCode == KeyEvent.VK_F4) { jumpToSource(); } } } private class DeleteListener extends KeyAdapter { @Override public void keyPressed(KeyEvent e) { final int keyCode = e.getKeyCode(); if (keyCode == KeyEvent.VK_DELETE) { delete(); } } } private class EnterListener extends KeyAdapter { @Override public void keyPressed(KeyEvent e) { final int keyCode = e.getKeyCode(); if (keyCode == KeyEvent.VK_ENTER) { run(); } } } private class DoubleClickListener extends MouseAdapter { public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { TestFile o = getTestFileAtPoint(e.getPoint()); new RunAutotestInIntelliJ().runInIDEA(project, o); } } } private class DeleteAction extends DumbAwareAction { public DeleteAction() { super("Delete (Del)"); } @Override public void actionPerformed(@NotNull AnActionEvent e) { delete(); } } private class RunAction extends DumbAwareAction { public RunAction() { super("Run", null, AllIcons.Toolwindows.ToolWindowRun); } @Override public void actionPerformed(@NotNull AnActionEvent e) { run(); } } private class DebugAction extends DumbAwareAction { public DebugAction() { super("Debug", null, AllIcons.Toolwindows.ToolWindowDebugger); } @Override public void actionPerformed(@NotNull AnActionEvent e) { debug(); } } private class RunOnAction extends DumbAwareAction { public RunOnAction() { super("Run Against..."); } @Override public void actionPerformed(@NotNull AnActionEvent e) { String environment = DialogUtils.chooseEnvironment(); if (environment != null) { Set<TestFile> testFileList = new HashSet<TestFile>(); for (Object o : list.getSelectedValues()) { TestFile o1 = (TestFile) o; TestFile element = new TestFile(environment, o1.getName(), o1.getPath(), o1.getFullPath()); if (!testFileList.contains(element)) { testFileList.add(element); AutotestState.getInstance().addTestFile(element); new RunAutotestInIntelliJ().runInIDEA(project, element); } } } } } private class JumpToSourceAction extends DumbAwareAction { public JumpToSourceAction() { super("Jump to Source (F4)"); } @Override public void actionPerformed(@NotNull AnActionEvent e) { jumpToSource(); } @Override public void update(@NotNull AnActionEvent e) { super.update(e); e.getPresentation().setVisible(list.getSelectedValues().length == 1); } } }